package com.avit.tv.kui;

import android.content.Context;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import androidx.annotation.ColorRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.avit.tv.kui.base.BaseFocusLayout;
import com.avit.tv.kui.list.AvitBaseAdapter;
import com.avit.tv.kui.list.OnChildSelectedListener;
import com.avit.tv.kui.list.OnKeyEventCallback;
import com.avit.tv.kui.list.OnListDataChangedListener;
import com.avit.tv.kui.utils.Log;

/**
 * 列表view
 * @author like
 * @date 2020/6/10
 */
public class AvitListView extends BaseFocusLayout implements View.OnKeyListener, AdapterView.OnItemSelectedListener {

    private  ListView listView;
    private AvitBaseAdapter avitBaseAdapter;
    @LayoutRes
    private int headLayout;
    @LayoutRes
    private int footLayout;
    @ColorRes
    private int listSelectColor;
    private Drawable listSelectDrawable;
    private Drawable listDivider;
    private int listDividerHeight;
    private boolean isStartOverRoll;
    private boolean isChildFocus;
    private int childFocusPosition;

    private View currentSelectView;

    /**
     * 按键监听
     */
    private OnKeyEventCallback keyEventCallback;

    /**
     * 子view 选中监听
     */
    private OnChildSelectedListener childSelectedListener;

    /**
     * 监听adapter 数据变化
     */
    private OnListDataChangedListener listDataChangedListener;

    private MyDataSetObserver dataSetObserve;

    public AvitListView(@NonNull Context context) {
        super(context);
    }

    public AvitListView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public AvitListView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }
    @Override
    protected void initView(Context context, AttributeSet attrs, int defStyleAttr) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs,
                R.styleable.AvitListView, defStyleAttr, 0);
        headLayout = typedArray.getResourceId(R.styleable.AvitListView_list_head, DEFAULT_RESOURCE);
        footLayout = typedArray.getResourceId(R.styleable.AvitListView_list_foot, DEFAULT_RESOURCE);
        listSelectColor = typedArray.getResourceId(R.styleable.AvitListView_list_selector_color, android.R.color.transparent);
        listSelectDrawable = typedArray.getDrawable(R.styleable.AvitListView_list_selector_bg);
        listDivider = typedArray.getDrawable(R.styleable.AvitListView_list_divider);
        listDividerHeight = typedArray.getDimensionPixelSize(R.styleable.AvitListView_list_divider_height, 0);
        isStartOverRoll = typedArray.getBoolean(R.styleable.AvitListView_is_start_over_roll, false);
        isChildFocus = typedArray.getBoolean(R.styleable.AvitListView_is_child_focus_well, false);
        childFocusPosition = typedArray.getInt(R.styleable.AvitListView_child_focus_item_position, 0);
        typedArray.recycle();
        dataSetObserve = new MyDataSetObserver();
    }

    @Override
    protected void initContent(Context context) {
        listView = new ListView(context);
        listView.setDivider(listDivider);
        listView.setDividerHeight(listDividerHeight);
        if (listSelectDrawable !=null)
            listView.setSelector(listSelectDrawable);
        else
            listView.setSelector(listSelectColor);
        listView.setOnItemSelectedListener(this);
        listView.setOnKeyListener(this);
    }


    @Override
    protected void insertView() {
        LayoutParams layoutparams = new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT);
        initHead();
        initFoot();
        addView(listView,layoutparams);
    }


    @Override
    protected void initFocus() {
        loseFocus(true);
        setSelection(0);
        if (isChildFocus)
            listView.setItemsCanFocus(true);
        else
            listView.setItemsCanFocus(false);

    }

    /**
     * 设置 listview 选中目标条目
     * @param position
     */
    public void setSelection(int position){
        listView.requestFocus();
        if (position == 0){
            listView.setSelectionAfterHeaderView();
        }else {
            int headerViewsCount = listView.getHeaderViewsCount();
            listView.setSelection(position+headerViewsCount);
        }
    }

    private void initHead(){
        if (headLayout != DEFAULT_RESOURCE){
            View view = initItemLayout(headLayout);
            listView.addHeaderView(view);
        }
    }

    private void initFoot(){
        if (footLayout!= DEFAULT_RESOURCE){
            View view = initItemLayout(footLayout);
            listView.addFooterView(view);
        }
    }

    private View initItemLayout(@LayoutRes int layoutRes){
        View initView = LayoutInflater.from(getContext()).inflate(layoutRes, this, false);
        initView.setFocusable(false);
        initView.setFocusableInTouchMode(false);
        return initView;
    }

    private View initItemView(View view){
        view.clearFocus();
        view.setFocusable(false);
        view.setFocusableInTouchMode(false);
        return view;
    }

    private void initAutoOverRoll(int keycode){
        if (avitBaseAdapter==null)return;
        if (isStartOverRoll){
            switch (keycode){
                case KeyEvent.KEYCODE_DPAD_DOWN:
                    if (listView.getSelectedItemPosition() == avitBaseAdapter.getCount()-1){
                        setSelection(0);
                    }
                    break;
                case KeyEvent.KEYCODE_DPAD_UP:
                    if (listView.getSelectedItemPosition() == 0){
                        setSelection(avitBaseAdapter.getCount()-1);
                    }
                    break;
            }
        }
    }

    /**
     * 获取 listview 的适配器
     *
     * @return
     */
    public AvitBaseAdapter getAvitBaseAdapter() {
        return avitBaseAdapter;
    }

    /**
     * 设置适配器
     *
     * @param adapter
     */
    public void setAdapter(AvitBaseAdapter adapter){
        avitBaseAdapter = adapter;
        listView.setAdapter(adapter);
        avitBaseAdapter.registerDataSetObserver(dataSetObserve);
    }

    /**
     * 设置listview 头部布局
     *
     * @param headLayout
     */
    public void setHeadLayout(@LayoutRes int headLayout) {
        this.headLayout = headLayout;
        initHead();
    }

    /**
     * 设置 listview 头部的view
     * @param view
     */
    public void setHeadView(View view){
        listView.addHeaderView(initItemView(view));
    }


    /**
     * 设置底部布局
     *
     * @param footLayout
     */
    public void setFootLayout(@LayoutRes int footLayout) {
        this.footLayout = footLayout;
        initFoot();
    }

    /**
     * 设置底部view
     * @param view
     */
    public void setFootView(View view){
        listView.addFooterView(initItemView(view));
    }

    /**
     * 设置listview 选中条目的背景色
     *
     * @param listSelectColor
     */
    public void setListSelectColor(@ColorRes int listSelectColor) {
        this.listSelectColor = listSelectColor;
        listView.setSelector(listSelectColor);
    }

    /**
     * 设置listView 选中条目的drawable
     * @param listSelectDrawable
     */
    public void setListSelectDrawable(Drawable listSelectDrawable) {
        this.listSelectDrawable = listSelectDrawable;
        listView.setSelector(listSelectDrawable);
    }

    /**
     * 设置分割线的图像
     *
     * @param listDivider
     */
    public void setListDivider(Drawable listDivider) {
        this.listDivider = listDivider;
        listView.setDivider(listSelectDrawable);
    }

    /**
     * 设置分割线的高度
     *
     * @param listDividerHeight
     */
    public void setListDividerHeight(int listDividerHeight) {
        this.listDividerHeight = listDividerHeight;
        listView.setDividerHeight(listDividerHeight);
    }

    /**
     * 是否开启无限循环，即上下按键按往顶部或底部时，循环滚动
     *
     * @param startOverRoll
     */
    public void setStartOverRoll(boolean startOverRoll) {
        isStartOverRoll = startOverRoll;
    }

    /**
     * 是否开启item 内部子控件自动锁焦
     * @param childFocus
     */
    public void setChildFocus(boolean childFocus) {
        isChildFocus = childFocus;
        initFocus();
    }

    /**
     * 设置按键监听
     *
     * @param keyEventCallback
     */
    public void setKeyEventCallback(OnKeyEventCallback keyEventCallback) {
        this.keyEventCallback = keyEventCallback;
    }

    /**
     * 设置item对应的子view 应该获取焦点的子view position
     * @param childFocusPosition
     */
    public void setChildFocusPosition(int childFocusPosition) {
        this.childFocusPosition = childFocusPosition;
    }


    /**
     * 设置selection 的监听
     * @param childSelectedListener
     */
    public void setChildSelectedListener(OnChildSelectedListener childSelectedListener) {
        this.childSelectedListener = childSelectedListener;
    }

    /**
     * 设置adpater 监听数据变化
     * @param listDataChangedListener
     */
    public void setListDataChangedListener(OnListDataChangedListener listDataChangedListener) {
        this.listDataChangedListener = listDataChangedListener;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKey(View v, int keyCode, KeyEvent event) {
        boolean tempFlag = false;
        if (event.getAction() == KeyEvent.ACTION_DOWN){
            switch (event.getKeyCode()){
                case KeyEvent.KEYCODE_DPAD_RIGHT:
                    Log.w(this, "enter right key");
                    tempFlag = true;
                    if (keyEventCallback!=null) {
                        keyEventCallback.onKeyRight();
                    }
                    break;
                case KeyEvent.KEYCODE_DPAD_LEFT :
                    Log.w(this, "enter left key");
                    tempFlag = true;
                    if (keyEventCallback!=null) {
                        keyEventCallback.onKeyLeft();
                    }
                    break;
                case KeyEvent.KEYCODE_DPAD_UP :
                case KeyEvent.KEYCODE_DPAD_DOWN:
                case KeyEvent.KEYCODE_CHANNEL_UP:
                case KeyEvent.KEYCODE_CHANNEL_DOWN:
                    if (childSelectedListener!=null)
                        childSelectedListener.beforeSelected(listView, currentSelectView);
                    initAutoOverRoll(event.getKeyCode());
                    break;
            }
        }
        return tempFlag;
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
        try {
            ViewGroup rootView = (ViewGroup) view;
            if (rootView.getChildCount()>0&&isChildFocus)
                rootView.getChildAt(childFocusPosition).requestFocus();
            if (childSelectedListener!=null)
                childSelectedListener.onSelected(position, view);
            currentSelectView = view;
        }catch (NullPointerException e){
            Log.e(this,"NullPointerException :" + e.getMessage());
        }catch (ClassCastException e){
            Log.e(this,"ClassCastException :" + e.getMessage());
        }
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {

    }


    private final class MyDataSetObserver extends DataSetObserver {
        @Override
        public void onChanged() {
            super.onChanged();
            Log.w(this,"view data notify changed");
            if (listDataChangedListener!=null)
                listDataChangedListener.onSetDataChanged();
        }

        @Override
        public void onInvalidated() {
            super.onInvalidated();
            Log.w(this,"view data invalidated changed");
            if (listDataChangedListener!=null)
                listDataChangedListener.onSetInvalidated();
        }
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        if (avitBaseAdapter!=null&& dataSetObserve!=null){
            avitBaseAdapter.unregisterDataSetObserver(dataSetObserve);
        }
    }
}
